/*
 * sw_drv.c
 *
 * Created: 05.03.2013 21:36:34
 *  Author: Timmo
 *
 *  The debounce functions are mainly based on Peter Dannegers code
 *  http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine
 *  The inherent timer interrupt routine can be found in MultiTrigge2.0.c file
 *  Instead of using a dedicated pin for each switch only one analog-pin is
 *  used determine which key is pressed and returned by read_sw() as uint8
 *
 */ 

#include <stdint.h>
#include <avr/interrupt.h>

#include "sw_drv.h"
#include "adc_drv.h"
#include "timer_functions.h"
#include "settings.h"

volatile uint8_t key_state;                       // debounced and inverted key state:
                                                  // bit = 1: key pressed
volatile uint8_t key_press;                       // key press detect
volatile uint8_t key_rpt;                                  // key long press and repeat


uint8_t read_sw(void){
	uint8_t val;
	val = (uint8_t)(ADC_read_ch0()/10);
	
	if(mt_settings.PCB_Revision > 9){
		// If any key is pressed reset the display standby timer
		if(val < 160)
			display_standby_timer = 0;
		
		if(val>11 && val < 16)
			return ~(1<<KEY_OK);
		if(val>52 && val < 58)
			return ~(1<<KEY_LEFT);
		if(val>64 && val < 70)
			return ~(1<<KEY_UP);
		if(val>25 && val < 31)
			return ~(1<<KEY_RIGHT);
		if(val>40 && val < 46)
			return ~(1<<KEY_DOWN);	
		
	}
	else{
		// If any key is pressed reset the display standby timer
		if(val < 200)
			display_standby_timer = 0;
		
		if(val>33 && val < 40)
			return ~(1<<KEY_OK);
		if(val>130 && val < 150)
			return ~(1<<KEY_LEFT);
		if(val>165 && val < 200)
			return ~(1<<KEY_UP);
		if(val>70 && val < 80)
			return ~(1<<KEY_RIGHT);
		if(val>100 && val < 115)
			return ~(1<<KEY_DOWN);
	}
	return ~0;
}

uint8_t get_key_rpt( uint8_t key_mask ){
	cli();                                          // read and clear atomic !
	key_mask &= key_rpt;                            // read key(s)
	key_rpt ^= key_mask;                            // clear key(s)
	sei();
	return key_mask;
}

uint8_t get_key_press( uint8_t key_mask )
{
  cli();                                          // read and clear atomic !
  key_mask &= key_press;                          // read key(s)
  key_press ^= key_mask;                          // clear key(s)
  sei();
  return key_mask;
}

uint8_t get_key_short( uint8_t key_mask )
{
  cli();                                          // read key state and key press atomic !
  return get_key_press( ~key_state & key_mask );
}

uint8_t get_key_long( uint8_t key_mask ){
	return get_key_press( get_key_rpt( key_mask ));
}